#ifndef BMC_TLPR_WIN32_LIBRARY__
#define BMC_TLPR_WIN32_LIBRARY__
/*
 * GPL
 * Free soft,no warranted
 * We are all in the mud, but some of us are looking at the stars.
 * We are not born for ourselves.
 * Author kofshower@gmail.com
 */
/**
 * @file win32_library_speific.h
 * @Synopsis library operator in win32, need link boost_filesystem
 * @author Chai JunJun
 * @date 2009-06-11
 */
#ifndef IS_MSVC
#error "This header file is only for Visual C compiler!"
#endif

#include <winbase.h>


typedef HMODULE TLHModule_t;
typedef TLInt32 TLStatus;

#define TL_CC_VER_1	    (_MSC_VER/100)
/* Disable CRT deprecation warnings. */
#if TL_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE
#endif
#if TL_CC_VER_1 >= 8 && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
    /* The above doesn't seem to work, at least on VS2005, so lets use
     * this construct as well.
     */
#pragma warning(disable: 4996)
#endif

#ifdef __cplusplus
#define TL_INLINE_SPECIFIER	inline
#else
#define TL_INLINE_SPECIFIER	static __inline
#endif

#define TL_EXPORT_DECL_SPECIFIER    __declspec(dllexport)
#define TL_EXPORT_DEF_SPECIFIER	    __declspec(dllexport)
#define TL_IMPORT_DECL_SPECIFIER    __declspec(dllimport)
#define TL_ATTR_NORETURN
#pragma warning(disable: 4127) // conditional expression is constant
#pragma warning(disable: 4611) // not wise to mix setjmp with C++
#pragma warning(disable: 4514) // unref. inline function has been removed
#pragma warning(disable: 4819)
#ifdef NDEBUG
#pragma warning(disable: 4702) // unreachable code
#pragma warning(disable: 4710) // function is not inlined.
#pragma warning(disable: 4711) // function selected for auto inline expansion
#endif

TL_INLINE_SPECIFIER string ws2s(const wstring& ws);
TL_INLINE_SPECIFIER wstring s2ws(const string& s);


/* -------------------------------------------------------------------------- */
/** @Synopsis  TLLoadLiraryByName Exception safe
 *
 * @Param libname posix-style path
 * @Param hModule
 *
 * @Returns
 */
/* ---------------------------------------------------------------------------- */
TL_INLINE_SPECIFIER TLStatus TLLoadLiraryByName(const string& libname, TLHModule_t& hModule)
{
#ifdef UNICODE
	boost::filesystem::wpath full_path( boost::filesystem::initial_path<boost::filesystem::wpath>() );
	full_path = boost::filesystem::complete(s2ws(libname));
	if(!boost::filesystem::exists(full_path) || !boost::filesystem::is_regular(full_path))
		return -1;

	if( NULL == (hModule = LoadLibraryW(full_path.file_string().c_str()) ) )
		return -1;
	return 0;
#else
    boost::filesystem::path full_path( boost::filesystem::initial_path<boost::filesystem::path>() );
    full_path = boost::filesystem::complete(libname);
    if(!boost::filesystem::exists(full_path) || !boost::filesystem::is_regular(full_path))
        return -1;

    if( NULL == (hModule = LoadLibraryA(full_path.file_string().c_str()) ) )
        return -1;
    return 0;
#endif
}

/* -------------------------------------------------------------------------- */
/** @Synopsis  function pointer
 */
/* ---------------------------------------------------------------------------- */

typedef void* TLHandleSym_t;

/* -------------------------------------------------------------------------- */
/** @Synopsis  TLGetProcAddress
 *
 * @Param hModule
 * @Param symname
 * @Param ressym
 *
 * @Returns
 */
/* ---------------------------------------------------------------------------- */
TL_INLINE_SPECIFIER TLStatus TLGetProcAddress(TLHModule_t hModule, const char* symname, TLHandleSym_t *ressym)
{
    *ressym = (TLHandleSym_t)GetProcAddress(hModule, symname);
    if(!*ressym)
        return -1;
    return 0;
}

/* -------------------------------------------------------------------------- */
/** @Synopsis  TLUnloadLibrary
 *
 * @Param hModule
 *
 * @Returns
 */
/* ---------------------------------------------------------------------------- */

TL_INLINE_SPECIFIER TLStatus TLUnloadLibrary(TLHModule_t hModule)
{
   if(FreeLibrary(hModule))
       return 0;
   return -1;
}

#endif //BMC_TLPR_WIN32_LIBRARY__

